package com.gd.iot.energy.service.datamanage.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gd.iot.energy.code.ResponseCode;
import com.gd.iot.energy.consts.SystemConsts;
import com.gd.iot.energy.dao.systemadmin.EquipCollectPOMapper;
import com.gd.iot.energy.exception.MyException;
import com.gd.iot.energy.po.systemadmin.AreaArchivesPO;
import com.gd.iot.energy.pojo.common.vo.ColumnVO;
import com.gd.iot.energy.pojo.common.vo.PageVO;
import com.gd.iot.energy.pojo.datamanage.dto.ReadMeterPageDTO;
import com.gd.iot.energy.pojo.datamanage.vo.HasReadMeterPageVO;
import com.gd.iot.energy.pojo.datamanage.vo.NotReadMeterPageVO;
import com.gd.iot.energy.pojo.datamanage.vo.ReadMeterPageVO;
import com.gd.iot.energy.service.dailymanage.CustomerFeeService;
import com.gd.iot.energy.service.datamanage.ReadMeterService;
import com.gd.iot.energy.service.systemadmin.AreaOrganizationService;
import com.gd.iot.energy.util.CustomColumnUtil;
import com.gd.iot.energy.util.CustomExcelOperateUtil;
import com.gd.iot.energy.util.EnergyTypeUtil;
import com.gd.iot.energy.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 抄表数据
 *
 * @author kris
 */
@Service
public class ReadMeterServiceImpl implements ReadMeterService {
    /**
     * 已抄表表头配置文件
     */
    private static final String HAS_READ_METER_LIST_COLUMN_FILE_NAME = "datamanage/has_read_metre_list.column";

    /**
     * 未抄表数据表头配置文件
     */
    private static final String NOT_READ_METER_LIST_COLUMN_FILE_NAME = "datamanage/not_read_metre_list.column";

    @Autowired
    private AreaOrganizationService areaOrganizationService;

    @Resource
    private EquipCollectPOMapper equipCollectPOMapper;

    @Autowired
    private CustomerFeeService customerFeeService;

    @Override
    public PageVO<? extends ReadMeterPageVO> getReadMeterPageVO(Integer type, String customerSerialnumber,
                                                                String customerName,
                                                                String archivesAddress,
                                                                String beginDate, String endDate,
                                                                Integer areaId,
                                                                Integer pageSize, Integer pageNum) {

        if(type == null||beginDate == null){
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }
        if(type.equals(SystemConsts.READ_METER_TYPE.HISTORY.value) &&endDate == null){
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        IPage<ReadMeterPageDTO> page = new Page<>(pageNum, pageSize);

        List<AreaArchivesPO> areaArchivesPOS = customerFeeService.selectByParams(customerSerialnumber, customerName,
                null, areaId, archivesAddress);

        List<Long> archiveIds = areaArchivesPOS.stream().map(AreaArchivesPO::getId)
                .collect(Collectors.toList());

        //为防止档案为空，放一个不存在的-999999查询条件
        archiveIds = archiveIds.isEmpty() ? Arrays.asList(-999999L) : archiveIds;
        QueryWrapper<ReadMeterPageDTO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        queryWrapper.in("id",archiveIds);

        if (SystemConsts.READ_METER_TYPE.YES.value.equals(type)) {
            return getHasReadMeterPage(type, beginDate, pageSize, pageNum, page, queryWrapper);
        } else if (SystemConsts.READ_METER_TYPE.NO.value.equals(type)) {
            return getNotReadMeterPage(type, beginDate, pageSize, pageNum, page, queryWrapper);
        } else {
            return getHistoryReadMeterPage(beginDate,endDate, pageSize, pageNum, page, queryWrapper);
        }
    }

    @Override
    public void exportReadMeterVO(Integer type, String customerSerialnumber, String customerName, String archivesAddress, String beginDate, String endDate, Integer areaId) {
        PageVO<? extends ReadMeterPageVO> chargeListPageVO = getReadMeterPageVO(type,customerSerialnumber,customerName,
                archivesAddress,beginDate,endDate,areaId,Integer.MAX_VALUE,1);
        String fileName = "Read_Meter_List_" +  DateUtil.current(false);
        String file = CustomExcelOperateUtil.exportExcel(SystemConsts.TEMP_FILE_PATH, fileName,
                chargeListPageVO.getColumns(), chargeListPageVO.getData());
        ResponseUtil.download(file, fileName + SystemConsts.EXCEL_SUFFIX);
    }

    /**
     * 抄表历史
     * @param beginDate
     * @param endDate
     * @param pageSize
     * @param pageNum
     * @param page
     * @param queryWrapper
     * @return
     */
    private PageVO<? extends ReadMeterPageVO> getHistoryReadMeterPage(String beginDate, String endDate,
                                                                      Integer pageSize, Integer pageNum,
                                                                      IPage<ReadMeterPageDTO> page,
                                                                      QueryWrapper<ReadMeterPageDTO> queryWrapper) {
        IPage<ReadMeterPageDTO> readMeterPageDTOPage = equipCollectPOMapper.selectHistoryReadMeterPage(page, queryWrapper,
                beginDate.trim(),endDate.trim());

        PageVO<HasReadMeterPageVO> pageVO = new PageVO<>();
        pageVO.setPageSize(pageSize);
        pageVO.setPageNum(pageNum);
        List<HasReadMeterPageVO> hasReadMeterPageVOS = convertToHasReadMeterPageVO(readMeterPageDTOPage.getRecords());
        pageVO.setData(hasReadMeterPageVOS);
        pageVO.setTotal(readMeterPageDTOPage.getTotal());
        pageVO.setPages(readMeterPageDTOPage.getPages());

        //表头
        List<ColumnVO> columns = CustomColumnUtil.getColumn(HAS_READ_METER_LIST_COLUMN_FILE_NAME);
        pageVO.setColumns(columns);
        return pageVO;
    }

    /**
     * 未抄表
     * @param type
     * @param beginDate
     * @param pageSize
     * @param pageNum
     * @param page
     * @param queryWrapper
     * @return
     */
    private PageVO<? extends ReadMeterPageVO> getNotReadMeterPage(Integer type, String beginDate, Integer pageSize, Integer pageNum, IPage<ReadMeterPageDTO> page, QueryWrapper<ReadMeterPageDTO> queryWrapper) {
        IPage<ReadMeterPageDTO> notReadPage = equipCollectPOMapper.selectReadMeterPage(page, queryWrapper,type,beginDate.trim());

        PageVO<NotReadMeterPageVO> pageVO = new PageVO<>();
        pageVO.setPageSize(pageSize);
        pageVO.setPageNum(pageNum);
        List<NotReadMeterPageVO> notReadMeterPageVOS = convertToNotReadMeterPageVO(notReadPage.getRecords());
        pageVO.setData(notReadMeterPageVOS);
        pageVO.setTotal(notReadPage.getTotal());
        pageVO.setPages(notReadPage.getPages());

        //表头
        List<ColumnVO> columns = CustomColumnUtil.getColumn(NOT_READ_METER_LIST_COLUMN_FILE_NAME);
        pageVO.setColumns(columns);
        return pageVO;
    }

    /**
     * 未抄表dto转vo
     * @param records
     * @return
     */
    private List<NotReadMeterPageVO> convertToNotReadMeterPageVO(List<ReadMeterPageDTO> records) {
        List<NotReadMeterPageVO> res = new ArrayList<>(records.size());
        NotReadMeterPageVO notReadMeterPageVO;
        long i = 1;
        for (ReadMeterPageDTO record : records) {
            notReadMeterPageVO = new NotReadMeterPageVO();
            notReadMeterPageVO.setId(i);
            notReadMeterPageVO.setSerialNum(i);
            notReadMeterPageVO.setCustomerName(record.getCustomerName());
            notReadMeterPageVO.setCustomerSerialnumber(record.getCustomerSerialnumber());
            notReadMeterPageVO.setSerialnumber(record.getSerialnumber());
            notReadMeterPageVO.setCollectChannel(SystemConsts.COLLECT_CHANNEL.getValuenameByValue(record.getCollectChannel()));
            notReadMeterPageVO.setMeasureEquipCollect(record.getMeasureEquipCollect());
            notReadMeterPageVO.setMeasureEquipConcent(record.getMeasureEquipConcent());
            res.add(notReadMeterPageVO);
            i++;
        }
        return res;
    }

    /**
     * 已抄表
     * @param type
     * @param beginDate
     * @param pageSize
     * @param pageNum
     * @param page
     * @param queryWrapper
     * @return
     */
    private PageVO<? extends ReadMeterPageVO> getHasReadMeterPage(Integer type, String beginDate, Integer pageSize, Integer pageNum, IPage<ReadMeterPageDTO> page, QueryWrapper<ReadMeterPageDTO> queryWrapper) {
        IPage<ReadMeterPageDTO> readMeterPageDTOPage = equipCollectPOMapper.selectReadMeterPage(page, queryWrapper,type,beginDate.trim());

        PageVO<HasReadMeterPageVO> pageVO = new PageVO<>();
        pageVO.setPageSize(pageSize);
        pageVO.setPageNum(pageNum);
        List<HasReadMeterPageVO> hasReadMeterPageVOS = convertToHasReadMeterPageVO(readMeterPageDTOPage.getRecords());
        pageVO.setData(hasReadMeterPageVOS);
        pageVO.setTotal(readMeterPageDTOPage.getTotal());
        pageVO.setPages(readMeterPageDTOPage.getPages());

        //表头
        List<ColumnVO> columns = CustomColumnUtil.getColumn(HAS_READ_METER_LIST_COLUMN_FILE_NAME);
        pageVO.setColumns(columns);
        return pageVO;
    }

    /**
     * 已抄表dto转vo
     * @param records
     * @return
     */
    private List<HasReadMeterPageVO> convertToHasReadMeterPageVO(List<ReadMeterPageDTO> records) {
        List<HasReadMeterPageVO> res = new ArrayList<>(records.size());
        HasReadMeterPageVO hasReadMeterPageVO;
        long i = 1;
        for (ReadMeterPageDTO record : records) {
            hasReadMeterPageVO = new HasReadMeterPageVO();
            hasReadMeterPageVO.setId(i);
            hasReadMeterPageVO.setSerialNum(i);
            hasReadMeterPageVO.setDosage(record.getDosage().setScale(2, RoundingMode.HALF_UP).toPlainString());
            hasReadMeterPageVO.setCustomerName(record.getCustomerName());
            hasReadMeterPageVO.setCustomerSerialnumber(record.getCustomerSerialnumber());
            hasReadMeterPageVO.setLastReadMeterTime(record.getReadMeterTime());
            hasReadMeterPageVO.setLastReadingnum(record.getLastReadingnum());
            hasReadMeterPageVO.setReadMeterTime(record.getReadMeterTime());
            hasReadMeterPageVO.setReadingnum(record.getReadingnum());
            hasReadMeterPageVO.setSerialnumber(record.getSerialnumber());
            res.add(hasReadMeterPageVO);
            i++;
        }
        return res;
    }

}
